package practice.library.slick


import scala.concurrent.ExecutionContext

/**
  * Created by lovepocky(lovepocky@foxmail.com) on 2016/4/3.
  */
object CodeGeneration {
    /**
      * reference to:
      * [http://slick.typesafe.com/doc/3.1.1/code-generation.html]
      * [https://github.com/tototoshi/slick-joda-mapper]
      */

    import slick.driver.JdbcProfile

    val maidi = new MysqlDataBaseConfig("maidi", "jdbc:mysql://120.55.67.152:3306/maididev?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false", "root", "maididev")

    val miduoduo = new MysqlDataBaseConfig("miduoduo", "jdbc:mysql://120.27.147.172:3306/miduoduodb?characterEncoding=utf8", "miduoduouser", "B632miduoduo")

    class MysqlDataBaseConfig(databaseName: String, val url: String, val user: String, val password: String) extends DatabaseConfig {
        override val slickDriver: String = "slick.driver.MySQLDriver"
        override val jdbcDriver: String = "com.mysql.jdbc.Driver"
        override val driver: JdbcProfile = slick.driver.MySQLDriver
        override val pkg: String = s"models.${databaseName}"
    }

    trait DatabaseConfig {
        val slickDriver: String
        val jdbcDriver: String
        val driver: JdbcProfile
        val outputFolder: String = "./generate"
        val url: String
        val pkg: String = "models"
        val user: String
        val password: String
    }

    def generateModels(databaseConfig: DatabaseConfig): Unit = {
        val slickDriver = databaseConfig.slickDriver
        val jdbcDriver = databaseConfig.jdbcDriver
        val driver: JdbcProfile = databaseConfig.driver
        val url = databaseConfig.url
        val pkg = databaseConfig.pkg
        val user = databaseConfig.user
        val password = databaseConfig.password

        implicit val ec: ExecutionContext = ExecutionContext.global

        val outputFolder = "./generate"

        val db = {
            //UNCOMMENT this if your database doesn't need credentials
            // driver.simple.Database.forURL(url, jdbcDriver)
            driver.api.Database.forURL(url, driver = jdbcDriver, user = user, password = password)
        }

        val modelFuture = db.run(driver.createModel(Some(driver.defaultTables)))

        val codegenFuture = modelFuture.map(model => new CustomSourceCodeGenerator(model))

        codegenFuture.onSuccess { case codegen =>
            codegen.writeToFile(slickDriver, outputFolder, pkg)
            println("Code Generate Complete, Please Check if Code was generated")
        }
        println("Code Generating")
    }
}

import slick.{model => m}
import slick.codegen.SourceCodeGenerator

class CustomSourceCodeGenerator(model: m.Model) extends SourceCodeGenerator(model) {

    // add some custom imports
    // TODO: fix these imports to refer to your JdbcSupport and your Joda imports
    //	override def code = "import com.github.tototoshi.slick.PostgresJodaSupport._\n" + "import org.joda.time.DateTime\n" + super.code
    override def code = "import com.github.tototoshi.slick.MySQLJodaSupport._\n" + "import org.joda.time.DateTime\n" + super.code

    override def Table = new Table(_) {
        override def Column = new Column(_) {

            // munge rawType -> SQL column type HERE (scaladoc in Slick 2.1.0 is outdated or incorrect, GeneratorHelpers#mapJdbcTypeString does not exist)
            // you can filter on model.name for the column name or model.tpe for the column type
            // your IDE won't like the String here but don't worry, the return type the compiler expects here is String
            override def rawType = model.tpe match {
                case "java.sql.Timestamp" => "DateTime" // kill j.s.Timestamp
                case _ => {
                    //          println(s"${model.table.table}#${model.name} tpe=${model.tpe} rawType=${super.rawType}")
                    super.rawType
                }
            }
        }
    }
}